package service

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/vueadmin/app/admin/dto"
	"github.com/vueadmin/app/admin/model"
	"github.com/vueadmin/app/admin/vo"
	"github.com/vueadmin/global"
	"github.com/vueadmin/utils/conv"
	"gorm.io/gorm"
)

var AdminGoodsCataService = new(adminGoodsCata)

type adminGoodsCata struct{}

/**
 * @description(数据列表)
 * @buildcode(true)
 */
func (p adminGoodsCata) GetPageList(req *dto.AdminGoodsCataPageReq) ([]*vo.AdminGoodsCataList, int64, error) {
	var (
		entity model.AdminGoodsCata
		list   []*vo.AdminGoodsCataList
		count  int64
	)
	query := global.DB.Model(&entity)
	if !conv.IsEmpty(req.ClassId) {
		query = query.Where("class_id = ?", req.ClassId)
	}
	if !conv.IsEmpty(req.SupplierId) {
		query = query.Where("supplier_id = ?", req.SupplierId)
	}
	if !conv.IsEmpty(req.Status) {
		query = query.Where("status = ?", req.Status)
	}
	order := "sortid asc"
	if !conv.IsEmpty(req.Sort) && !conv.IsEmpty(req.Order) {
		order = fmt.Sprintf("%s %s", req.Sort, req.Order)
	}
	query = query.Preload("Supplier", func(db *gorm.DB) *gorm.DB {
		return db.Select("supplier_id,supplier_name")
	})
	if err := query.Limit(req.Limit).Offset((req.Page - 1) * req.Limit).Order(order).Find(&list).Error; err != nil {
		return nil, 0, err
	}
	query.Count(&count)

	return p.getTreeList(list, 0), count, nil
}

/**
 * @description(格式化成树形结构列表)
 * @buildcode(true)
 */
func (p adminGoodsCata) getTreeList(list []*vo.AdminGoodsCataList, pid int) []*vo.AdminGoodsCataList {
	res := make([]*vo.AdminGoodsCataList, 0)
	for _, v := range list {
		if v.Pid == pid {
			v.Children = p.getTreeList(list, conv.Int(v.ClassId))
			res = append(res, v)
		}
	}
	return res
}

/**
 * @description(修改排序开关)
 * @buildcode(true)
 */
func (p adminGoodsCata) UpdateExt(req map[string]interface{}) error {
	entity := model.AdminGoodsCata{}
	if err := global.DB.Model(&entity).Where("class_id", req["class_id"]).Updates(req).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(添加)
 * @buildcode(true)
 */
func (p adminGoodsCata) Add(req *dto.AdminGoodsCataAddReq) (uint, error) {
	entity := model.AdminGoodsCata{}
	entity.ClassName = req.ClassName
	entity.SupplierId = req.SupplierId
	entity.Pid = req.Pid
	entity.Status = req.Status
	entity.Sortid = req.Sortid

	if err := global.DB.Create(&entity).Error; err != nil {
		return 0, err
	}
	if entity.Sortid == 0 {
		if err := global.DB.Model(&entity).Update("sortid", entity.ClassId).Error; err != nil {
			return 0, err
		}
	}
	return entity.ClassId, nil
}

/**
 * @description(修改)
 * @buildcode(true)
 */
func (p adminGoodsCata) Update(req *dto.AdminGoodsCataUpdateReq) error {
	entity := model.AdminGoodsCata{
		ClassId: req.ClassId,
	}
	if err := global.DB.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	entity.ClassName = req.ClassName
	entity.SupplierId = req.SupplierId
	entity.Pid = req.Pid
	entity.Status = req.Status
	entity.Sortid = req.Sortid

	field := conv.StringToSlice("class_name,supplier_id,pid,status,sortid", ",")

	if err := global.DB.Select(field).Updates(&entity).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(获取修改详情)
 * @buildcode(true)
 */
func (p adminGoodsCata) GetUpdateInfo(req *dto.AdminGoodsCataGetUpdateInfoReq) (*model.AdminGoodsCata, error) {
	entity := model.AdminGoodsCata{}
	if err := global.DB.Where("class_id = ?", req.ClassId).Limit(1).First(&entity).Error; err != nil {
		return nil, err
	}
	return &entity, nil
}

/**
 * @description(删除)
 * @buildcode(true)
 */
func (p adminGoodsCata) Delete(req *dto.AdminGoodsCataDeleteReq) error {
	query := global.DB.Where("class_id IN ?", conv.Slice(req.ClassId))
	if err := query.Delete(&model.AdminGoodsCata{}).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(查看详情)
 * @buildcode(true)
 */
func (p adminGoodsCata) Detail(req *dto.AdminGoodsCataDetailReq) (*vo.AdminGoodsCataDetail, error) {
	var info vo.AdminGoodsCataDetail
	query := global.DB.Model(&model.AdminGoodsCata{})
	if err := query.Where("class_id = ?", req.ClassId).Limit(1).First(&info).Error; err != nil {
		return nil, err
	}
	return &info, nil
}

/**
 * @description(查询sql下拉字段列表)
 * @buildcode(true)
 */
func (p adminGoodsCata) GetFieldList(c *gin.Context) (map[string]interface{}, error) {
	var (
		SupplierId []*vo.AdminGoodsCataSupplierId
		Pid        []*vo.AdminGoodsCataPid
	)
	if err := global.DB.Raw(`select supplier_id,supplier_name from cd_supplier`).Scan(&SupplierId).Error; err != nil {
		return nil, err
	}
	if err := global.DB.Raw(`select class_id,class_name,pid from cd_goods_cata`).Scan(&Pid).Error; err != nil {
		return nil, err
	}
	data := make(map[string]interface{})
	data["supplier_ids"] = SupplierId
	data["pids"] = p.getTreePid(Pid, 0)
	return data, nil
}

/**
 * @description(查询所属父类联动)
 * @buildcode(true)
 */
func (p adminGoodsCata) GetPidList(req *dto.AdminGoodsCataPidReq) ([]*vo.AdminGoodsCataPid, error) {
	var Pid []*vo.AdminGoodsCataPid
	sql := fmt.Sprintf(`select class_id,class_name,pid from cd_goods_cata where supplier_id = %d`, req.SupplierId)
	if err := global.DB.Raw(sql).Scan(&Pid).Error; err != nil {
		return nil, err
	}
	return p.getTreePid(Pid, 0), nil
}

/**
 * @description(格式所属父类树形结构)
 * @buildcode(true)
 */
func (p adminGoodsCata) getTreePid(list []*vo.AdminGoodsCataPid, pid int) []*vo.AdminGoodsCataPid {
	res := make([]*vo.AdminGoodsCataPid, 0)
	for _, v := range list {
		if v.Pid == pid {
			v.Children = p.getTreePid(list, v.ClassId)
			res = append(res, v)
		}
	}
	return res
}
